/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package eu.easyedu.dictionary.api.nservice.spi;

import eu.easyedu.dictionary.api.nservice.impl.*;
import eu.easyedu.dictionary.api.model.Dictionary;
import java.util.List;
import java.util.logging.Logger;
import eu.easyedu.dictionary.api.model.Language;
import eu.easyedu.dictionary.api.model.Word;
import eu.easyedu.dictionary.api.nservice.spi.WordBookService;
import eu.easyedu.dictionary.api.options.DictionaryOptions;
import eu.easyedu.dictionary.api.options.Options;
import eu.easyedu.dictionary.api.service.events.SearchEvent;
import eu.easyedu.dictionary.api.service.events.SearchEventListener;
import eu.easyedu.dictionary.api.service.events.SearchResultEvent;
import java.util.ArrayList;
import javax.swing.SwingUtilities;
import org.netbeans.api.progress.ProgressHandle;
import org.netbeans.api.progress.ProgressHandleFactory;
import org.openide.util.Lookup;
import org.openide.util.RequestProcessor;

/**
 *
 * @author hlavki
 */
public class AsynchronousSearch extends Thread {

    private static final Logger log = Logger.getLogger(AsynchronousSearch.class.getName());
    private String searchString;
    private Language language;
//    private JList list;
    private WordBookService wordBookService;
    Dictionary dictionary;
    private List<SearchEventListener> searchEventListeners;

    public AsynchronousSearch(Dictionary dictionary) {
        this.dictionary = dictionary;
        this.wordBookService = Lookup.getDefault().lookup(WordBookService.class);
        searchEventListeners = new ArrayList<SearchEventListener>();
    }

    public RequestProcessor.Task search(String searchString, Language language) {
        if (isAlive()) {
            log.info("Another older search in progress. Interrupting...");
            interrupt();
        }
        this.searchString = searchString;
        this.language = language;
        return RequestProcessor.getDefault().post(this);
    }

    @Override
    public void run() {
        fireSearchStartedEvent(searchString);
        log.info("Thread search " + Thread.currentThread());
        ProgressHandle handle = ProgressHandleFactory.createHandle("Searching for word: " + searchString);
        handle.start(100);
        log.fine("Searching word: " + searchString + " using search type " + SearchType.START_WITH);
        Options opts = DictionaryOptions.getInstance();
        List<Word> result = wordBookService.getAllWords(dictionary, searchString, language, SearchType.START_WITH);
        handle.progress(50);
        handle.finish();
        fireSearchStoppedEvent(result);
    }

    private final void fireSearchStartedEvent(final String searchString) {
        try {
            SwingUtilities.invokeAndWait(new Runnable() {

                public void run() {
                    SearchEvent evt = new SearchEvent(searchString);
                    for (SearchEventListener listener : searchEventListeners) {
                        listener.searchStarted(evt);
                    }
                }
            });
        } catch (Exception e) {
        // oh well we got interrupted.
        }
    }

    private final void fireSearchStoppedEvent(final List<Word> searchResult) {
        try {
            SwingUtilities.invokeAndWait(new Runnable() {

                public void run() {
                    SearchResultEvent evt = new SearchResultEvent(searchResult);
                    for (SearchEventListener listener : searchEventListeners) {
                        listener.searchStopped(evt);
                    }
                }
            });
        } catch (Exception e) {
        // oh well we got interrupted.
        }
    }

    public void addSearchEventListener(SearchEventListener listener) {
        searchEventListeners.add(listener);
    }

    public void removeSearchEventListener(SearchEventListener listener) {
        searchEventListeners.remove(listener);
    }
}
